# -*- coding: utf-8 -*-
# @Author : zhaochen
# @Date   : 2019/1/22
# @File   : IC16_Past2YearsLoanCardQuasiAccOvduMons.py
# @E-mail : zhaochen@bbdservice.com

'''eof
name:过去两年贷款和（准）贷记卡最长单笔（非连续）累计逾期月份数
code:IC16_Past2YearsLoanCardQuasiAccOvduMons
tableName:
columnName:
groups:个人征信模块
dependencies:IC_DSJ
type:常用指标
datasourceType:在线指标
description:
eof'''

import sys
import re
import datetime
reload(sys)
sys.setdefaultencoding('utf-8')

null_type_list = ['', ' ', None, 'null', 'Null', 'NULL', '/', '-', '--']

def getTable(table_Name):
    try:
        data = IC_DSJ['data'].get(table_Name)
        if data in null_type_list:
            return None
        else:
            # 存在1条为空的数据[{}]
            if isinstance(data, list) and len(data) == 1 and data[0]['reportNo'] in null_type_list:
                return [{}]
            # 存在表 但为空list []
            elif isinstance(data, list) and len(data) == 0:
                return None
            else:
                return data
    except:
        return None

def isReportNo(x):
    try:
        if len(x) == 1:
            is_reportno = x[0].get('reportNo')
            if is_reportno in null_type_list:
                return False
            else:
                return True
        else:
            return True
    except:
        return False

def isfloat(x):
    '''
    判断x为float类型且大于等于0
    :param x:
    :return:
    '''
    try:
        if isinstance(float(x), float) and float(x)>=0:
            if str(x) in ['inf', 'infinity', 'INF', 'INFINITY', 'True']:
                return False
            else:
                return True
        else:
            return False
    except:
        return False



def Past2YearsLoanCardQuasiAccOvduMonsPre(*args):
    try:
        #时间节点 转化为 月份
        monthToday = datetime.datetime.now().year * 12 + datetime.datetime.now().month
        monthTwoYearsAgo = (datetime.datetime.now().year - 2) * 12 + datetime.datetime.now().month
        #贷款明细表
        icrLoanInfo002LoanList = getTable(args[0])
        #贷款5年逾期记录表
        icrLatest5YearOverdueDetailList = getTable(args[1])

        # 对最近2年明细记录处理
        #不存在该表
        if icrLoanInfo002LoanList is None:
            result1 = None
        #存在该表 但是无记录
        elif icrLoanInfo002LoanList == [{}]:
            result1 = {}
        else:
            # 有记录
            flag = []
            result1 = {}
            for row1 in icrLoanInfo002LoanList:
                # 若24个月状态为空，则计其在 icrLoanInfo002Loan中逾期次数为0；
                if row1.get('latest24State') in null_type_list:
                    if row1.get('account') not in null_type_list:
                        key = row1.get('account')
                        result1.update({key:0})
                    else:
                        flag.append(None)
                        continue
                else:
                    # 若24个月状态不为空 则统计逾期次数
                    # 准贷记卡逾期容忍度为2个月
                    if args[0] == 'ICRStdLoancardInfo002*Std':
                        latest24State = row1.get('latest24State')
                        pattern = re.compile('[3-7]')
                        count1 = len(pattern.findall(latest24State))
                    else:
                        latest24State = row1.get('latest24State')
                        pattern = re.compile('[1-7]')
                        count1 = len(pattern.findall(latest24State))
                    #以account为key存24个月中逾期个数
                    if row1.get('account') not in null_type_list:
                        key = row1.get('account')
                        result1.update({key:count1})
                    else:
                        flag.append(None)
                        continue
            # account 缺失
            if len(flag) == len(icrLoanInfo002LoanList):
                result1 = None

        # 对5年逾期记录表处理
        # 若5年逾期记录表缺失
        if icrLatest5YearOverdueDetailList is None:
            result2 = None
        # 5年逾期记录表 为空
        elif icrLatest5YearOverdueDetailList == [{}]:
            result2 = {}
        else:
            #
            flag = []
            result2 = {}
            for row2 in icrLatest5YearOverdueDetailList:
                if row2.get('account') not in null_type_list \
                        and row2.get('month') not in null_type_list and isfloat(row2.get('lastMonths')):
                    #用account匹配
                    account = row2.get('account')
                    month = row2.get('month')
                    monthFact = float(month[:4]) * 12 + float(month[5:])
                    # 对准贷记卡做特殊处理
                    if float(row2.get('lastMonths'))>=1 and float(row2.get('lastMonths'))<=7:
                        if args[1] == 'ICRLatest5YearOverdueDetail*Std':
                            if monthFact > monthTwoYearsAgo and monthFact <= monthToday:
                                if float(row2.get('lastMonths')) > 2:
                                    for j in range(int(float(row2.get('lastMonths')))-2):
                                        if (monthFact - j) > monthTwoYearsAgo:
                                            if not result2.get(account):
                                                result2.update({account: [monthFact - j]})
                                            else:
                                                result2.get(account).append(monthFact - j)
                        else:
                            # 处理 非准贷记卡
                            if monthFact > monthTwoYearsAgo and monthFact <= monthToday:
                                for j in range(int(float(row2.get('lastMonths')))):
                                    if (monthFact - j) > monthTwoYearsAgo:
                                        if not result2.get(account):
                                            result2.update({account:[monthFact-j]})
                                        else:
                                            result2.get(account).append(monthFact-j)
                    else:
                        flag.append(None)
                        continue
                else:
                    flag.append(None)
                    continue
            if len(flag) == len(icrLatest5YearOverdueDetailList):
                result2 = None

        # 若result1 和 result2 同时为空
        if result1 is None and result2 is None:
            return None
        # 任一为空或{} 则置为0后计算
        elif result1 in [None, {}] and result2 != None:
            if result2 == {}:
                return 0
            else:
                result = {}
                for k in result2:
                    result.update({k:len(set(result2.get(k)))})
                return max(result.values())

        elif result1 != None and result2 in [None, {}]:
            # print result1
            if result1 == {}:
                return 0
            else:
                return max(result1.values())
        # 同时为{} 置为0
        elif result1 == {} and result2 == {}:
            return 0

        elif len(result1) != 0 and len(result2) != 0:
            result = {}
            # 合并 result1 和 result2 的逾期月份数
            for k in result1:
                if result2.get(k) not in null_type_list:
                    count2 = len(set(result2.get(k)))
                    count = result1.get(k) + count2
                    result.update({k:count})
                else:
                    result.update({k:result1.get(k)})
            return max(result.values()) if result!={} else 0
        else:
            assert False

    except:
        return None

def IC16_Past2YearsLoanCardQuasiAccOvduMons():
    try:
        #贷款信息
        dk = Past2YearsLoanCardQuasiAccOvduMonsPre(*('ICRLoanInfo002*Loan', 'ICRLatest5YearOverdueDetail*Loan'))
        #贷记卡信息
        djk = Past2YearsLoanCardQuasiAccOvduMonsPre(*('ICRLoancardInfo002*Card', 'ICRLatest5YearOverdueDetail*Card'))
        #准贷记卡信息
        zdjk = Past2YearsLoanCardQuasiAccOvduMonsPre(*('ICRStdLoancardInfo002*Std', 'ICRLatest5YearOverdueDetail*Std'))

        if dk is None and djk is None and zdjk is None:
            return u'缺失值'
        else:
            dk = dk if dk !=None else 0
            djk = djk if djk !=None else 0
            zdjk = zdjk if zdjk !=None else 0
            return max(dk, djk, zdjk)
    except:
        return u'缺失值'

result = IC16_Past2YearsLoanCardQuasiAccOvduMons()